import 'dart:convert';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:pt_manage/common/global.dart';
import 'package:pt_manage/dao/site_dao.dart';
import 'package:pt_manage/db/query/query_config.dart';
import 'package:pt_manage/generated/l10n.dart';
import 'package:pt_manage/model/Site.dart';
import 'package:pt_manage/util/toast_util.dart';
import 'package:textfield_tags/textfield_tags.dart';

class AddSite extends StatefulWidget {
  const AddSite({super.key});

  @override
  State<AddSite> createState() => _AddSiteState();

}

class _AddSiteState extends State<AddSite> {
  final Site _site = Site();
  final _formKey = GlobalKey<FormState>();
  final _selectSiteController = TextEditingController();
  final _tagFocusNode = FocusNode();
  final _stringTagController = StringTagController();
  final _schemaController = TextEditingController();
  final _passKeyController = TextEditingController();
  final _urlController = TextEditingController();
  final _descController = TextEditingController();

  final _timezone = [
    {"value": "-1200", "text": "(UTC -12:00) Enitwetok, Kwajalien"},
    {"value": "-1100", "text": "(UTC -11:00) Midway Island, Samoa"},
    {"value": "-1000", "text": "(UTC -10:00) Hawaii"},
    {"value": "-0900", "text": "(UTC -09:00) Alaska"},
    {"value": "-0800", "text": "(UTC -08:00) Pacific Time (US & Canada)"},
    {"value": "-0700", "text": "(UTC -07:00) Mountain Time (US & Canada)"},
    {
      "value": "-0600",
      "text": "(UTC -06:00) Central Time (US & Canada), Mexico City"
    },
    {
      "value": "-0500",
      "text": "(UTC -05:00) Eastern Time (US & Canada), Bogota, Lima"
    },
    {
      "value": "-0400",
      "text": "(UTC -04:00) Atlantic Time (Canada), Caracas, La Paz"
    },
    {"value": "-0330", "text": "(UTC -03:30) Newfoundland"},
    {
      "value": "-0300",
      "text": "(UTC -03:00) Brazil, Buenos Aires, Falkland Is."
    },
    {
      "value": "-0200",
      "text": "(UTC -02:00) Mid-Atlantic, Ascention Is., St Helena"
    },
    {"value": "-0100", "text": "(UTC -01:00) Azores, Cape Verde Islands"},
    {
      "value": "+0000",
      "text": "(UTC ±00:00) Casablanca, Dublin, London, Lisbon, Monrovia"
    },
    {
      "value": "+0100",
      "text": "(UTC +01:00) Brussels, Copenhagen, Madrid, Paris"
    },
    {"value": "+0200", "text": "(UTC +02:00) Sofia, Izrael, South Africa,"},
    {"value": "+0300", "text": "(UTC +03:00) Baghdad, Riyadh, Moscow, Nairobi"},
    {"value": "+0330", "text": "(UTC +03:30) Tehran"},
    {"value": "+0400", "text": "(UTC +04:00) Abu Dhabi, Baku, Muscat, Tbilisi"},
    {"value": "+0430", "text": "(UTC +04:30) Kabul"},
    {"value": "+0500", "text": "(UTC +05:00) Ekaterinburg, Karachi, Tashkent"},
    {
      "value": "+0530",
      "text": "(UTC +05:30) Bombay, Calcutta, Madras, New Delhi"
    },
    {"value": "+0600", "text": "(UTC +06:00) Almaty, Colomba, Dhakra"},
    {"value": "+0700", "text": "(UTC +07:00) Bangkok, Hanoi, Jakarta"},
    {
      "value": "+0800",
      "text": "(UTC +08:00) ShangHai, HongKong, Perth, Singapore, Taipei"
    },
    {
      "value": "+0900",
      "text": "(UTC +09:00) Osaka, Sapporo, Seoul, Tokyo, Yakutsk"
    },
    {"value": "+0930", "text": "(UTC +09:30) Adelaide, Darwin"},
    {
      "value": "+1000",
      "text": "(UTC +10:00) Melbourne, Papua New Guinea, Sydney"
    },
    {
      "value": "+1100",
      "text": "(UTC +11:00) Magadan, New Caledonia, Solomon Is."
    },
    {"value": "+1200", "text": "(UTC +12:00) Auckland, Fiji, Marshall Island"}
  ];

  final _siteDao = Global.getDb<SiteDao>();

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    _selectSiteController.dispose();
    _tagFocusNode.dispose();
    _stringTagController.dispose();
    _schemaController.dispose();
    _passKeyController.dispose();
    _urlController.dispose();
    _descController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        resizeToAvoidBottomInset: true,
        appBar: _buildAppBar(context),
        body: _buildBody(context),
      ),
    );
  }

  PreferredSizeWidget _buildAppBar(BuildContext context) {
    return AppBar(
      title: Text(S.of(context).siteAdd),
    );
  }

  Widget _buildBody(BuildContext context) {
    return Padding(
        padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
        child: SingleChildScrollView(
          child: Form(
            key: _formKey,
            child: Column(
              mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                const SizedBox(
                  height: 20,
                ),
                _buildSelectSite(context),
                const SizedBox(
                  height: 20,
                ),
                _buildSelectTags(context),
                const SizedBox(
                  height: 20,
                ),
                _buildTextField(context, S.of(context).siteSchema, _schemaController),
                const SizedBox(
                  height: 20,
                ),
                _buildTextField(context, S.of(context).passKey, _passKeyController,
                    enabled: true, hintText: S.of(context).passKeyEmptyTip),
                const SizedBox(
                  height: 20,
                ),
                _buildTextField(context, S.of(context).siteUrl, _urlController),
                const SizedBox(
                  height: 20,
                ),
                _buildDropdownButtonFormField(
                    context,
                    S.of(context).siteTimezone,
                    _timezone
                        .map((tz) => DropdownMenuItem<String>(
                      value: tz['value'],
                      child: Text(
                        tz['text']!,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ))
                        .toList(),
                        (val) {},
                    _site.timezoneOffset),
                const SizedBox(
                  height: 20,
                ),
                _buildTextField(context, S.of(context).siteDescription, _descController, enabled: true),
                const SizedBox(
                  height: 20,
                ),
                Row(
                  children: <Widget>[
                    Expanded(
                      child: ElevatedButton(
                        child: Padding(
                          padding: const EdgeInsets.all(16.0),
                          child: Text(S.of(context).siteAdd),
                        ),
                        onPressed: () => _siteAdd(context),
                      ),
                    ),
                  ],
                )
              ],
            ),
          ),
        )
    );
  }

  void _siteAdd(BuildContext context) async {
    if (_formKey.currentState!.validate())  {
      bool exist = await _siteDao.existQuery(QueryConfig(field: "url", condition: Condition.EQ, value: _site.url));
      if (exist) {
        ToastUtil.show(S.of(context).siteExistTip);
        return;
      }
      _siteDao.insert(_site);
      Navigator.pop(context);
    }
  }

  Widget _buildSelectSite(BuildContext context) {
    return FutureBuilder(
      future: DefaultAssetBundle.of(context).loadString("lib/json/sites.json"),
      builder: (context, snapshot) {
        List<dynamic> sites = jsonDecode(snapshot.data.toString()) ?? [];
        return Padding(
          padding: const EdgeInsets.symmetric(horizontal: 10),
          child: DropdownButtonFormField2<String>(
            value: _site.url,
            isExpanded: true,
            isDense: false,
            decoration: InputDecoration(
              labelText: S.of(context).site,
              contentPadding: const EdgeInsets.symmetric(vertical: 16),
              border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(15),
              ),
            ),
            hint: Text(
              S.of(context).siteSelect,
              style: const TextStyle(fontSize: 14),
            ),
            items: sites
                .map((item) => DropdownMenuItem<String>(
                      value: item['url'],
                      child: ListTile(
                        isThreeLine: true,
                        dense: true,
                        title: Text(
                          item['name'],
                          style: const TextStyle(fontSize: 14),
                        ),
                        leading: CachedNetworkImage(
                          width: 36,
                          height: 36,
                          fit: BoxFit.fill,
                          imageUrl: item['icon'] ?? '',
                          cacheKey: item['icon'],
                          placeholder: (context, url) =>
                              const CircularProgressIndicator(),
                          errorWidget: (context, url, error) =>
                              const Icon(Icons.error),
                        ),
                        subtitle: Text(
                          item['url'],
                          style: const TextStyle(fontSize: 12),
                        ),
                      ),
                      onTap: () {
                        _stringTagController.clearTags();
                        final tags = item['tags'] ?? [];
                        for (var tag in tags) {
                          _stringTagController.onTagSubmitted(tag);
                        }
                        _tagFocusNode.unfocus();
                        _schemaController.text = item['schema'];
                        _urlController.text = item['url'];
                        _descController.text = item['description'];

                        setState(() {
                          _site.name = item['name'];
                          _site.url = item['url'];
                          _site.icon = item['icon'];
                          _site.tags = tags.cast<String>();
                          _site.host = item['host'];
                          _site.cdn = item['cdn'] == null ? [] : (item['cdn'] as List<dynamic>).cast<String>();
                          _site.apiCdn = item['apiCdn'] == null ? [] : (item['apiCdn'] as List<dynamic>).cast<String>();
                          _site.schema = item['schema'];
                          _site.timezoneOffset = item['timezoneOffset'];
                          _site.description = item['description'];
                        });
                      },
                    ))
                .toList(),
            validator: (value) {
              if (value == null) return S.of(context).siteSelect;
              return null;
            },
            onChanged: (value) {},
            onSaved: (value) {},
            buttonStyleData: const ButtonStyleData(
              padding: EdgeInsets.only(right: 8),
            ),
            iconStyleData: const IconStyleData(
              icon: Icon(
                Icons.arrow_drop_down,
                color: Colors.black45,
              ),
              iconSize: 24,
            ),
            dropdownStyleData: DropdownStyleData(
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(15),
              ),
            ),
            menuItemStyleData: const MenuItemStyleData(
              padding: EdgeInsets.symmetric(horizontal: 16),
            ),
            dropdownSearchData: DropdownSearchData(
                searchController: _selectSiteController,
                searchInnerWidgetHeight: 50,
                searchInnerWidget: Container(
                  height: 50,
                  padding: const EdgeInsets.only(
                      top: 8, bottom: 4, right: 8, left: 8),
                  child: TextFormField(
                    expands: true,
                    maxLines: null,
                    controller: _selectSiteController,
                    decoration: InputDecoration(
                        isDense: true,
                        contentPadding: const EdgeInsets.symmetric(
                            horizontal: 10, vertical: 8),
                        hintText: S.of(context).enterKeywordSearch,
                        hintStyle: const TextStyle(fontSize: 12),
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(8))),
                  ),
                ),
                searchMatchFn: (item, searchValue) =>
                    item.value.toString().contains(searchValue)),
            onMenuStateChange: (isOpen) {
              if (!isOpen) _selectSiteController.clear();
            },
          ),
        );
      },
    );
  }

  Widget _buildSelectTags(BuildContext context) {
    return TextFieldTags<String>(
        textfieldTagsController: _stringTagController,
        initialTags: const [],
        focusNode: _tagFocusNode,
        validator: (String tag) {
          if (_stringTagController.getTags!.contains(tag)) return S.of(context).siteTagExists;
          return null;
        },
        inputFieldBuilder: (context, inputFieldValues) {
          return Padding(
            padding: const EdgeInsets.symmetric(horizontal: 10.0),
            child: TextField(
              onTap: () {
                _stringTagController.getFocusNode?.requestFocus();
              },
              controller: inputFieldValues.textEditingController,
              focusNode: inputFieldValues.focusNode,
              decoration: InputDecoration(
                enabled: true,
                labelText: S.of(context).siteTag,
                floatingLabelBehavior: FloatingLabelBehavior.always,
                isDense: true,
                border: OutlineInputBorder(
                  borderSide: const BorderSide(
                    color: Color.fromARGB(255, 74, 137, 92),
                    width: 3.0,
                  ),
                  borderRadius: BorderRadius.circular(15),
                ),
                focusedBorder: const OutlineInputBorder(
                  borderSide: BorderSide(
                    color: Color.fromARGB(255, 74, 137, 92),
                    width: 3.0,
                  ),
                ),
                helperStyle: const TextStyle(
                  color: Color.fromARGB(255, 74, 137, 92),
                ),
                hintText: inputFieldValues.tags.isNotEmpty ? '' : S.of(context).siteTag,
                errorText: inputFieldValues.error,
                prefixIconConstraints: BoxConstraints(
                    maxWidth: MediaQuery.of(context).size.width * 0.8),
                prefixIcon: inputFieldValues.tags.isNotEmpty
                    ? SingleChildScrollView(
                        controller: inputFieldValues.tagScrollController,
                        scrollDirection: Axis.vertical,
                        child: Padding(
                          padding: const EdgeInsets.only(
                            top: 8,
                            bottom: 8,
                            left: 8,
                          ),
                          child: Wrap(
                              runSpacing: 4.0,
                              spacing: 4.0,
                              children: inputFieldValues.tags.map((String tag) {
                                return Container(
                                  decoration: const BoxDecoration(
                                    borderRadius: BorderRadius.all(
                                      Radius.circular(20.0),
                                    ),
                                    color: Color.fromARGB(255, 74, 137, 92),
                                  ),
                                  margin: const EdgeInsets.symmetric(
                                      horizontal: 5.0),
                                  padding: const EdgeInsets.symmetric(
                                      horizontal: 10.0, vertical: 5.0),
                                  child: Row(
                                    mainAxisAlignment: MainAxisAlignment.start,
                                    mainAxisSize: MainAxisSize.min,
                                    children: [
                                      InkWell(
                                        child: Text(
                                          '#$tag',
                                          style: const TextStyle(
                                              color: Colors.white),
                                        ),
                                        onTap: () {
                                          //print("$tag selected");
                                        },
                                      ),
                                      const SizedBox(width: 4.0),
                                      InkWell(
                                        child: const Icon(
                                          Icons.cancel,
                                          size: 14.0,
                                          color: Color.fromARGB(
                                              255, 233, 233, 233),
                                        ),
                                        onTap: () {
                                          inputFieldValues.onTagRemoved(tag);
                                        },
                                      )
                                    ],
                                  ),
                                );
                              }).toList()),
                        ),
                      )
                    : null,
              ),
              onChanged: inputFieldValues.onTagChanged,
              onSubmitted: inputFieldValues.onTagSubmitted,
            ),
          );
        });
  }

  Widget _buildTextField(
      BuildContext context, String labelText, TextEditingController controller,
      {bool enabled = false, hintText = "", Key? key}) {
    return Padding(
      key: key,
      padding: const EdgeInsets.symmetric(horizontal: 10),
      child: TextField(
        enabled: enabled,
        controller: controller,
        decoration: InputDecoration(
          labelText: labelText,
          hintText: hintText,
          floatingLabelBehavior: FloatingLabelBehavior.always,
          border: const OutlineInputBorder(
            borderRadius: BorderRadius.all(Radius.circular(15)),
          ),
        ),
      ),
    );
  }

  Widget _buildDropdownButtonFormField<T>(
      BuildContext context,
      String labelText,
      List<DropdownMenuItem> items,
      ValueChanged onChanged,
      T value,
      {bool enabled = false}) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 10),
      child: DropdownButtonFormField(
        value: value,
        items: items,
        isExpanded: true,
        decoration: InputDecoration(
          labelText: labelText,
          floatingLabelBehavior: FloatingLabelBehavior.always,
          border: const OutlineInputBorder(
            borderRadius: BorderRadius.all(Radius.circular(15)),
          ),
        ),
        onChanged: onChanged,
      ),
    );
  }
}
